package ao.com.bna.controle;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import ao.com.bna.beans.MovimentoFornecedor;
import ao.com.bna.beans.Nota;
import ao.com.bna.dao.NotaDao;
import ao.com.bna.util.BeanFactory;
import ao.com.bna.util.JsfUtil;

@ManagedBean
@SessionScoped
public class NotaControle {
	private Nota infoBean = new Nota();
	private List<Nota> listaNotas = new ArrayList<Nota>();
	private NotaDao dao = (NotaDao) BeanFactory.getBean("notaDao",
			NotaDao.class);
	private List<NotaItem> listaNotaItem = new ArrayList<NotaItem>();
	// --------------------------------------------------------------------------------------------------
	private MovimentoFornecedor infoBeanItem = new MovimentoFornecedor();
	private MovimentoFornecedor infoBeanItemTmp = new MovimentoFornecedor();
	private List<MovimentoFornecedor> listaMovimentosItem = new ArrayList<MovimentoFornecedor>();
	private List<MovimentoFornecedor> listaMovimentosItemTmp = new ArrayList<MovimentoFornecedor>();
	// --------------------------------------------------------------------------------------------------
	private String estadoCorrente;
	private String paginaDestino;
	private String tituloPagina;

	public NotaControle() {
		actualizaTela();
	}

	/**
	 * @return the infoBean
	 */
	public Nota getInfoBean() {
		return infoBean;
	}

	/**
	 * @param infoBean
	 *            the infoBean to set
	 */
	public void setInfoBean(Nota infoBean) {
		this.infoBean = infoBean;
	}

	/**
	 * @return the listaInfos
	 */
	public ListDataModel<Nota> getListaInfos() {
		return new ListDataModel<Nota>(listaNotas);
	}

	/**
	 * @return the listaNotas
	 */
	public List<Nota> getListaNotas() {
		return listaNotas;
	}

	/**
	 * @param listaNotas
	 *            the listaNotas to set
	 */
	public void setListaNotas(List<Nota> listaNotas) {
		this.listaNotas = listaNotas;
	}

	/**
	 * @return the listaInfosItem
	 */
	public ListDataModel<MovimentoFornecedor> getListaInfosItem() {
		return new ListDataModel<MovimentoFornecedor>(listaMovimentosItem);
	}

	/**
	 * @return the infoBeanItem
	 */
	public MovimentoFornecedor getInfoBeanItem() {
		return infoBeanItem;
	}

	/**
	 * @param infoBeanItem
	 *            the infoBeanItem to set
	 */
	public void setInfoBeanItem(MovimentoFornecedor infoBeanItem) {
		this.infoBeanItem = infoBeanItem;
	}

	/**
	 * @return the infoBeanItemTmp
	 */
	public MovimentoFornecedor getInfoBeanItemTmp() {
		return infoBeanItemTmp;
	}

	/**
	 * @param infoBeanItemTmp
	 *            the infoBeanItemTmp to set
	 */
	public void setInfoBeanItemTmp(MovimentoFornecedor infoBeanItemTmp) {
		this.infoBeanItemTmp = infoBeanItemTmp;
	}

	/**
	 * @return the listaMovimentosItem
	 */
	public List<MovimentoFornecedor> getListaMovimentosItem() {
		return listaMovimentosItem;
	}

	/**
	 * @param listaMovimentosItem
	 *            the listaMovimentosItem to set
	 */
	public void setListaMovimentosItem(List<MovimentoFornecedor> listaMovimentosItem) {
		this.listaMovimentosItem = listaMovimentosItem;
	}

	/**
	 * @return the listaMovimentosItemTmp
	 */
	public List<MovimentoFornecedor> getListaMovimentosItemTmp() {
		return listaMovimentosItemTmp;
	}

	/**
	 * @param listaMovimentosItemTmp
	 *            the listaMovimentosItemTmp to set
	 */
	public void setListaPedidosItemTmp(
			List<MovimentoFornecedor> listaMovimentosItemTmp) {
		this.listaMovimentosItemTmp = listaMovimentosItemTmp;
	}
	


	/**
	 * @return the listaInfosNotaItem
	 */
	public ListDataModel<NotaItem> getListaInfosNotaItem() {
		return new ListDataModel<NotaItem>(listaNotaItem);
	}
	

	/**
	 * @return the listaNotaItem
	 */
	public List<NotaItem> getListaNotaItem() {
		return listaNotaItem;
	}

	/**
	 * @param listaNotaItem the listaNotaItem to set
	 */
	public void setListaNotaItem(List<NotaItem> listaNotaItem) {
		this.listaNotaItem = listaNotaItem;
	}

	/**
	 * @param listaMovimentosItemTmp the listaMovimentosItemTmp to set
	 */
	public void setListaMovimentosItemTmp(
			List<MovimentoFornecedor> listaMovimentosItemTmp) {
		this.listaMovimentosItemTmp = listaMovimentosItemTmp;
	}

	/**
	 * @return the dao
	 */
	public NotaDao getDao() {
		return dao;
	}

	/**
	 * @param dao
	 *            the dao to set
	 */
	public void setDao(NotaDao dao) {
		this.dao = dao;
	}

	private void actualizaTela() {
		infoBean = new Nota();
		listaNotas = dao.listar();
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloListar");
	}

	/**
	 * @see Metodo que ivoca o metodo gravar apartir da classe EstadoDao
	 */
	public String gravar() {
		try {
			Date dt = new Date();
			infoBean.setDataAlteracao((Date) dt.clone());
			if (this.isEstadoAdicionar() && this.listaMovimentosItem.size() > 0) {
				infoBean.setDataRegisto((Date) dt.clone());
				this.dao.gravar(getInfoBean(), getListaMovimentosItem());
					JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
					"resources.mensagens").getString("geralRegistoCriado"));
				actualizaTela();
				return this.preparaAdicionar();
			} else if (this.isEstadoActualizar() && this.listaMovimentosItem.size() > 0) {
				this.dao.gravar(getInfoBean());
				JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
						"resources.mensagens")
						.getString("geralRegistoAlterado"));
				// /actualizaTela();
				this.setEstadoCorrente(JsfUtil.ESTADO_FORMVAZIO);
				return null; // this.voltar();
			} else {
				JsfUtil.addWarnMessage("ATT: Falta de items.");
			}
			return null;
		} catch (Exception e) {
			JsfUtil.addErrorMessage(
					e,
					ResourceBundle.getBundle("resources.mensagens").getString(
							"geralErroDePersistencia"));
			return null;
		}
	}

	// ----------------------------------------------------------------------------

	/**
	 * @see Metodo que invoca o metodo gravar
	 */
	public String adicionarItem() {

		try {
			this.listaMovimentosItem.add(infoBeanItem);
			// this.listaPedidosItemTmp.add(infoBeanItemTmp);
			adicionarNotaItem(infoBeanItem);
			JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
					"resources.mensagens").getString("itemPedidoMsgAdicionar"));
			// this.setEstadoCorrente(JsfUtil.ESTADO_FORMVAZIO);
			actualizaTela();
			return null;
		} catch (Exception e) {
			JsfUtil.addErrorMessage(
					e,
					ResourceBundle.getBundle("resources.mensagens").getString(
							"Falha ao adicionar item"));
			return null;
		}
	}

	// ----------------------------------------------------------------------------

	/**
	 * @see Metodo que invoca o metodo gravar
	 */
	public void adicionarNotaItem(MovimentoFornecedor movimento) {
		//listaNotaItem
		for (NotaItem item : listaNotaItem) {
			if (item.getProduto().equals(movimento.getProduto())) {
				item.setQuantidade(item.getQuantidade() + 1);
				return;
			}
		}
		
		NotaItem item = new NotaItem();
		item.setProduto(movimento.getProduto());
		item.setQuantidade(1);
		listaNotaItem.add(item);
	}

	// ----------------------------------------------------------------------------

	/**
	 * @see Metodo que obtem um registo
	 */
	public Nota obterPorID() {
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloListar");
		return dao.obterPorID(getInfoBean().getId());
	}

	/**
	 * @see Metodo que ivoca o metodo remover apartir da classe EstadoDao
	 */
	public String excluir() {
		try {
			this.dao.remover(this.getInfoBean());
			JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
					"resources.mensagens").getString("geralRegistoEliminado"));
			this.setEstadoCorrente(JsfUtil.ESTADO_FORMVAZIO);
			return null; // this.voltar();
		} catch (Exception e) {
			JsfUtil.addErrorMessage(
					e,
					ResourceBundle.getBundle("resources.mensagens").getString(
							"geralErroDePersistencia"));
			return null;
		}
	}

	public SelectItem[] getItemsAvailableSelectOneEmpety() {
		List<Nota> lista = new ArrayList<Nota>();
		return JsfUtil.getSelectItems(lista, true);
	}

	public SelectItem[] getItemsAvailableSelectMany() {
		return JsfUtil.getSelectItems(this.dao.listar(), false);
	}

	public SelectItem[] getItemsAvailableSelectOne() {
		return JsfUtil.getSelectItems(this.dao.listar(), true);
	}

	@FacesConverter(value = "nota", forClass = Nota.class)
	public static class EntityConverter implements Converter {

		public Object getAsObject(FacesContext facesContext,
				UIComponent component, String value) {
			if (value == null || value.length() == 0) {
				return null;
			}
			NotaControle controller = (NotaControle) facesContext
					.getApplication()
					.getELResolver()
					.getValue(facesContext.getELContext(), null, "notaControle");
			return controller.dao.obterPorID(getKey(value));
		}

		java.lang.Long getKey(String value) {
			java.lang.Long key;
			key = Long.valueOf(value);
			return key;
		}

		String getStringKey(java.lang.Long value) {
			StringBuffer sb = new StringBuffer();
			sb.append(value);
			return sb.toString();
		}

		public String getAsString(FacesContext facesContext,
				UIComponent component, Object object) {
			if (object == null) {
				return null;
			}
			if (object instanceof Nota) {
				Nota o = (Nota) object;
				return getStringKey(o.getId());
			} else {
				throw new IllegalArgumentException("object " + object
						+ " is of type " + object.getClass().getName()
						+ "; expected type: " + Nota.class.getName());
			}
		}

	}

	/*
	 * MÈtodos que expıem o estado da pagina
	 */

	/**
	 * Prepara view detalhe
	 */
	public String preparaDetalhes() {
		this.setEstadoCorrente(JsfUtil.ESTADO_DETALHES);
		this.tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloDetalhes");
		return null;
	}

	public String novo() {
		this.infoBean = new Nota();
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"notaPaginaCRUD");
	}

	/**
	 * Prepara view adicionar
	 */
	public String preparaAdicionar() {
		this.setEstadoCorrente(JsfUtil.ESTADO_ADICIONAR);
		this.tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloRegistar");
		return novo();
	}

	/**
	 * Prepara view editar
	 */
	public String preparaEditar() {
		this.setEstadoCorrente(JsfUtil.ESTADO_ACTUALIZAR);
		this.tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloAlterar");
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"notaPaginaCRUD");
	}

	/**
	 * Prepara view eliminar
	 */
	public String preparaEliminar() {
		this.setEstadoCorrente(JsfUtil.ESTADO_ELIMINAR);
		this.tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("notaTituloEliminar");
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"notaPaginaCRUD");
	}

	/**
	 * Referente ao botao voltar
	 */
	public String voltar() {
		this.actualizaTela();
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"notaPaginaListar");
	}

	// //////////////////////////////////
	public boolean isEstadoPesquisar() {
		String state = this.getEstadoCorrente();
		return (state == null || JsfUtil.ESTADO_PESQUISAR.equals(state));
	}

	public boolean isEstadoAdicionar() {
		return JsfUtil.ESTADO_ADICIONAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoActualizar() {
		return JsfUtil.ESTADO_ACTUALIZAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoEliminar() {
		return JsfUtil.ESTADO_ELIMINAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoDetalhe() {
		return JsfUtil.ESTADO_DETALHES.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoFormVazio() {
		return JsfUtil.ESTADO_FORMVAZIO.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoCrud() {
		return (this.isEstadoAdicionar() || this.isEstadoActualizar()
				|| this.isEstadoEliminar() || this.isEstadoDetalhe() || this
				.isEstadoFormVazio());
	}

	/**
	 * @return the estadoCorrente
	 */
	public String getEstadoCorrente() {
		return estadoCorrente;
	}

	/**
	 * @param estadoCorrente
	 *            the estadoCorrente to set
	 */
	public void setEstadoCorrente(String estadoCorrente) {
		this.estadoCorrente = estadoCorrente;
	}

	/**
	 * @return the paginaDestino
	 */
	public String getPaginaDestino() {
		return paginaDestino;
	}

	/**
	 * @param paginaDestino
	 *            the paginaDestino to set
	 */
	public void setPaginaDestino(String paginaDestino) {
		this.paginaDestino = paginaDestino;
	}

	/**
	 * @return the tituloPagina
	 */
	public String getTituloPagina() {
		return tituloPagina;
	}

	/**
	 * @param tituloPagina
	 *            the tituloPagina to set
	 */
	public void setTituloPagina(String tituloPagina) {
		this.tituloPagina = tituloPagina;
	}

}
